package com.code.google.p.jyve;

import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;

import javax.swing.BoxLayout;
import javax.swing.DefaultListModel;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import org.eclipse.wb.swing.FocusTraversalOnArray;

import com.code.google.p.jyve.database.Stof;

public class DatabaseWindow {

	private JFrame frmDatabaseopties;
	private JTextField txtNaamBase;
	protected JTabbedPane tabbedPane;

	static private final int TAB_TOEVOEGEN = 0;
	static private final int TAB_AANPASSEN = 1;
	private JTextField txtAanpNaam;
	private JTextField txtAanpZuur;
	private JTextField txtAanpBase;
	private JTextField txtAanpKz;

	private DefaultListModel stoffen = new DefaultListModel();
	private JList list;
	private JTextField txtAanpKb;
	private JTextField txtKzToevoegen;
	private JTextField txtNaam1;

	private Stof selectedStof;
	private JTextPane error_aanpassen;

	private DecimalFormat format = new DecimalFormat("0.0E0");
	private JTextField txtNaam2;
	private JTextField txtNaam3;
	private JTextField txtNaam4;

	/**
	 * Create the application.
	 */
	public DatabaseWindow() {
		
		setStoffenArray();
		initialize();
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		frmDatabaseopties = new JFrame();
		frmDatabaseopties.setIconImage(Toolkit.getDefaultToolkit().getImage(DatabaseWindow.class.getResource("/com/code/google/p/jyve/Jyve3.png")));
		frmDatabaseopties.setTitle("Databaseopties");
		frmDatabaseopties.setBounds(100, 100, 450, 459);

		tabbedPane = new JTabbedPane(JTabbedPane.TOP);
		tabbedPane.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent arg0) {
				tabChange(tabbedPane.getSelectedIndex());
			}
		});
		frmDatabaseopties.getContentPane().setLayout(new BoxLayout(frmDatabaseopties.getContentPane(), BoxLayout.X_AXIS));
		frmDatabaseopties.getContentPane().add(tabbedPane);

		JPanel panel = new JPanel();
		panel.setBackground(Color.WHITE);
		tabbedPane.addTab("Toevoegen", null, panel, null);
		panel.setLayout(null);

		JLabel lblStoffenToevoegenAan = new JLabel("Zuur of base toevoegen aan de database");
		lblStoffenToevoegenAan.setFont(new Font("Tahoma", Font.BOLD, 14));
		lblStoffenToevoegenAan.setBounds(10, 11, 372, 14);
		panel.add(lblStoffenToevoegenAan);

		JLabel lblNaam = new JLabel("Namen / formules zuur");
		lblNaam.setFont(new Font("Tahoma", Font.PLAIN, 12));
		lblNaam.setBounds(10, 36, 192, 14);
		panel.add(lblNaam);

		JLabel lblBase = new JLabel("Geconjugeerde base");
		lblBase.setBounds(10, 148, 288, 14);
		panel.add(lblBase);

		txtNaamBase = new JTextField();
		txtNaamBase.setBounds(20, 173, 86, 20);
		panel.add(txtNaamBase);
		txtNaamBase.setColumns(10);

		final JTextPane errorLabel = new JTextPane();
		errorLabel.setBounds(289, 304, 116, 78);
		panel.add(errorLabel);

		JSplitPane splitPane = new JSplitPane();
		splitPane.setToolTipText("Aanpassen");
		tabbedPane.addTab("Aanpassen", null, splitPane, null);

		JScrollPane scrollPane = new JScrollPane();
		splitPane.setRightComponent(scrollPane);

		list = new JList();
		list.addListSelectionListener(new ListSelectionListener() {
			public void valueChanged(ListSelectionEvent arg0) {
				Stof stof = ((StofHolder)list.getSelectedValue()).stof;
				selectedStof = stof;
				showStof(stof);
			}
		});
		list.setModel(stoffen);
		scrollPane.setViewportView(list);

		JButton btnToevoegen = new JButton("Toevoegen");
		btnToevoegen.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				//addStof();
				//TODO: Maak af: toevoegen in database. Naamgeving werkt nog niet helemaal, probleem met ladingen;
				try{
					Stof.Builder builder = new Stof.Builder(txtNaam1.getText());
					String naamBase = txtNaamBase.getText();
					if (naamBase.length() != 0){
						Stof base;
						base = (base = Stof.findInstance(naamBase)) != null ? base : new Stof.Builder(naamBase).build();
						double kz = 0;
						try {
							kz = format.parse(txtKzToevoegen.getText()).doubleValue();
						}
						catch (ParseException parseException){
							errorLabel.setText("Kz is geen geldig getal");
							return;
						}
						builder.addBase(base, kz);
					}

					Stof stof = builder.addToDatabase().build();
					List<String> names = new ArrayList<String>();
					if (txtNaam2.getText().length() != 0){
						names.add(txtNaam2.getText());
						if (txtNaam3.getText().length() != 0){
							names.add(txtNaam3.getText());
							if (txtNaam4.getText().length() != 0){
								names.add(txtNaam4.getText());
							}
						}
					}
					
					for (String i : names){
						Stof kopie = new Stof(stof);
						kopie.setNaam(i);
						Stof.addToDatabase(kopie);
					}
					
					// Waardes terug zetten
					txtNaam1.setText(null);
					txtNaam2.setText(null);
					txtNaam3.setText(null);
					txtNaam4.setText(null);
					txtNaamBase.setText(null);
					txtKzToevoegen.setText(null);
					txtKzToevoegen.setText(null);

					setStoffenArray();
					list.repaint();
				}catch(Exception exception){
					exception.printStackTrace();
				}
			}
		});
		btnToevoegen.setBounds(10, 327, 123, 23);
		panel.add(btnToevoegen);

		JButton btnGereed = new JButton("Gereed");
		btnGereed.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				hide();
			}
		});
		btnGereed.setBounds(149, 328, 116, 23);
		panel.add(btnGereed);

		txtNaam1 = new JTextField();
		txtNaam1.addKeyListener(new KeyAdapter() {
			@Override
			public void keyReleased(KeyEvent arg0) {
				boolean enabled = txtNaam1.getText().length() != 0;
				txtNaam2.setEnabled(enabled);
				if (!enabled){
					txtNaam3.setEnabled(enabled);
					txtNaam4.setEnabled(enabled);
				}
			}
		});
		txtNaam1.setBounds(20, 61, 86, 20);
		panel.add(txtNaam1);
		txtNaam1.setColumns(10);

		JLabel lblKbToevoegen = new JLabel("Kz van dit deeltje");
		lblKbToevoegen.setBounds(10, 92, 96, 14);
		panel.add(lblKbToevoegen);

		txtKzToevoegen = new JTextField();
		txtKzToevoegen.setBounds(20, 117, 86, 20);
		panel.add(txtKzToevoegen);
		txtKzToevoegen.setColumns(10);
		
		txtNaam2 = new JTextField();
		txtNaam2.setEnabled(false);
		txtNaam2.addKeyListener(new KeyAdapter() {
			@Override
			public void keyReleased(KeyEvent e) {
				boolean enabled = txtNaam2.getText().length() != 0;
				txtNaam3.setEnabled(enabled);
				if (!enabled) txtNaam4.setEnabled(enabled);
			}
		});
		txtNaam2.setBounds(116, 61, 86, 20);
		panel.add(txtNaam2);
		txtNaam2.setColumns(10);
		
		txtNaam3 = new JTextField();
		txtNaam3.setEnabled(false);
		txtNaam3.addKeyListener(new KeyAdapter() {
			@Override
			public void keyReleased(KeyEvent e) {
				txtNaam4.setEnabled(txtNaam3.getText().length() != 0);
			}
		});
		txtNaam3.setBounds(212, 61, 86, 20);
		panel.add(txtNaam3);
		txtNaam3.setColumns(10);
		
		txtNaam4 = new JTextField();
		txtNaam4.setEnabled(false);
		txtNaam4.setBounds(308, 61, 86, 20);
		panel.add(txtNaam4);
		txtNaam4.setColumns(10);
		panel.setFocusTraversalPolicy(new FocusTraversalOnArray(new Component[]{txtNaam1, txtKzToevoegen, txtNaamBase, btnToevoegen, btnGereed, lblStoffenToevoegenAan, lblNaam, lblBase, errorLabel, lblKbToevoegen}));

		JLabel lblDatabaseStoffen = new JLabel("Database Stoffen");
		lblDatabaseStoffen.setFont(new Font("Tahoma", Font.BOLD, 14));
		scrollPane.setColumnHeaderView(lblDatabaseStoffen);

		JPanel panel_1 = new JPanel();
		panel_1.setBackground(Color.WHITE);
		splitPane.setLeftComponent(panel_1);

		JLabel lblGeselecteerde = new JLabel("Geselecteerd:");
		lblGeselecteerde.setFont(new Font("Tahoma", Font.BOLD, 14));

		JLabel lblNaam_1 = new JLabel("Naam of formule");
		lblNaam_1.setFont(new Font("Tahoma", Font.PLAIN, 12));

		txtAanpNaam = new JTextField();
		txtAanpNaam.setColumns(10);

		JLabel lblZuu = new JLabel("Geconjugeerd zuur (leeglaten indien niet aanwezig)");

		txtAanpZuur = new JTextField();
		txtAanpZuur.setColumns(10);

		JLabel lblBase_1 = new JLabel("Geconjugeerde base (leeglaten indien niet aanwezig)");

		txtAanpBase = new JTextField();
		txtAanpBase.setColumns(10);

		JButton btnToepassen = new JButton("Toepassen");
		btnToepassen.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				error_aanpassen.setText(null);
				String contentAanpassenNaam = txtAanpNaam.getText();
				if (contentAanpassenNaam.length() != 0){
					selectedStof.setNaam(contentAanpassenNaam);					
				}
				else {
					error_aanpassen.setText("Naam mag niet leeg zijn");
					return;
				}

				String contentAanpassenBase = txtAanpBase.getText();
				if (contentAanpassenBase.length() != 0){
					Stof base = Stof.findInstance(contentAanpassenBase);
					if (base == null) {
						error_aanpassen.setText("Base niet gevonden");
						return;
					}
					String contentKz = txtAanpKz.getText();
					double kz = 0;
					try {
						kz = format.parse(contentKz).doubleValue();
					}
					catch (ParseException exception){
						error_aanpassen.setText("Kz is geen geldig getal");
						return;
					}
					selectedStof.setBase(base, kz);
				}

				String contentAanpassenZuur = txtAanpZuur.getText();
				if (contentAanpassenZuur.length() != 0){
					Stof zuur = Stof.findInstance(contentAanpassenZuur);
					if (zuur == null){
						error_aanpassen.setText("Zuur niet gevonden");
						return;
					}
					String contentKb = txtAanpKb.getText();
					double kb = 0;
					try {
						kb = format.parse(contentKb).doubleValue();
					}
					catch (ParseException exception){
						error_aanpassen.setText("Kb is geen geldig getal");
						return;
					}
					selectedStof.setZuur(zuur, kb);
				}
			}
		});

		JButton btnGereed_1 = new JButton("Gereed");
		btnGereed_1.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent arg0) {
				hide();
			}
		});

		JLabel lblOverigeInformatie = new JLabel("Overige informatie");
		lblOverigeInformatie.setFont(new Font("Tahoma", Font.PLAIN, 12));

		JLabel lblKz = new JLabel("Kz van dit deeltje");

		txtAanpKz = new JTextField();
		txtAanpKz.setColumns(10);

		JLabel lblKb = new JLabel("Kb van dit deeltje");

		txtAanpKb = new JTextField();
		txtAanpKb.setColumns(10);

		error_aanpassen = new JTextPane();
		GroupLayout gl_panel_1 = new GroupLayout(panel_1);
		gl_panel_1.setHorizontalGroup(
			gl_panel_1.createParallelGroup(Alignment.LEADING)
				.addGroup(gl_panel_1.createSequentialGroup()
					.addContainerGap()
					.addComponent(lblNaam_1, GroupLayout.DEFAULT_SIZE, 155, Short.MAX_VALUE)
					.addGap(101))
				.addGroup(gl_panel_1.createSequentialGroup()
					.addContainerGap()
					.addComponent(lblBase_1)
					.addGap(148))
				.addGroup(gl_panel_1.createSequentialGroup()
					.addContainerGap()
					.addComponent(lblZuu)
					.addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
				.addGroup(gl_panel_1.createSequentialGroup()
					.addContainerGap()
					.addComponent(lblOverigeInformatie, GroupLayout.PREFERRED_SIZE, 152, GroupLayout.PREFERRED_SIZE)
					.addContainerGap(104, Short.MAX_VALUE))
				.addGroup(gl_panel_1.createSequentialGroup()
					.addGroup(gl_panel_1.createParallelGroup(Alignment.LEADING)
						.addGroup(gl_panel_1.createSequentialGroup()
							.addContainerGap()
							.addGroup(gl_panel_1.createParallelGroup(Alignment.LEADING)
								.addComponent(btnToepassen, GroupLayout.PREFERRED_SIZE, 108, GroupLayout.PREFERRED_SIZE)
								.addGroup(gl_panel_1.createSequentialGroup()
									.addGap(10)
									.addComponent(txtAanpKz, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
								.addComponent(lblKz)))
						.addGroup(gl_panel_1.createSequentialGroup()
							.addGap(20)
							.addComponent(txtAanpKb, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
						.addGroup(gl_panel_1.createSequentialGroup()
							.addContainerGap()
							.addComponent(lblKb)))
					.addGap(53)
					.addGroup(gl_panel_1.createParallelGroup(Alignment.LEADING, false)
						.addComponent(error_aanpassen, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
						.addComponent(btnGereed_1, GroupLayout.DEFAULT_SIZE, 85, Short.MAX_VALUE))
					.addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
				.addGroup(gl_panel_1.createSequentialGroup()
					.addContainerGap()
					.addComponent(lblGeselecteerde, GroupLayout.PREFERRED_SIZE, 163, GroupLayout.PREFERRED_SIZE)
					.addContainerGap(93, Short.MAX_VALUE))
				.addGroup(gl_panel_1.createSequentialGroup()
					.addGap(21)
					.addComponent(txtAanpBase, GroupLayout.PREFERRED_SIZE, 202, GroupLayout.PREFERRED_SIZE)
					.addContainerGap(43, Short.MAX_VALUE))
				.addGroup(gl_panel_1.createSequentialGroup()
					.addGap(20)
					.addComponent(txtAanpZuur, GroupLayout.PREFERRED_SIZE, 211, GroupLayout.PREFERRED_SIZE)
					.addContainerGap(35, Short.MAX_VALUE))
				.addGroup(gl_panel_1.createSequentialGroup()
					.addGap(20)
					.addComponent(txtAanpNaam, GroupLayout.PREFERRED_SIZE, 205, GroupLayout.PREFERRED_SIZE)
					.addContainerGap(41, Short.MAX_VALUE))
		);
		gl_panel_1.setVerticalGroup(
			gl_panel_1.createParallelGroup(Alignment.LEADING)
				.addGroup(gl_panel_1.createSequentialGroup()
					.addGap(30)
					.addComponent(lblGeselecteerde)
					.addGap(18)
					.addComponent(lblNaam_1)
					.addPreferredGap(ComponentPlacement.RELATED)
					.addComponent(txtAanpNaam, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
					.addGap(27)
					.addComponent(lblZuu)
					.addPreferredGap(ComponentPlacement.RELATED)
					.addComponent(txtAanpZuur, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
					.addPreferredGap(ComponentPlacement.RELATED)
					.addComponent(lblBase_1)
					.addPreferredGap(ComponentPlacement.RELATED)
					.addComponent(txtAanpBase, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
					.addPreferredGap(ComponentPlacement.RELATED)
					.addComponent(lblOverigeInformatie)
					.addPreferredGap(ComponentPlacement.RELATED)
					.addGroup(gl_panel_1.createParallelGroup(Alignment.LEADING)
						.addGroup(gl_panel_1.createSequentialGroup()
							.addComponent(lblKz)
							.addPreferredGap(ComponentPlacement.RELATED)
							.addComponent(txtAanpKz, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
							.addPreferredGap(ComponentPlacement.RELATED)
							.addComponent(lblKb)
							.addPreferredGap(ComponentPlacement.RELATED)
							.addComponent(txtAanpKb, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
						.addComponent(error_aanpassen, GroupLayout.PREFERRED_SIZE, 86, GroupLayout.PREFERRED_SIZE))
					.addGap(18)
					.addGroup(gl_panel_1.createParallelGroup(Alignment.BASELINE)
						.addComponent(btnToepassen)
						.addComponent(btnGereed_1))
					.addGap(85))
		);
		panel_1.setLayout(gl_panel_1);
	}

	private void showStof(Stof stof){
		txtAanpNaam.setText(stof.getNaam());
		Stof base;
		txtAanpBase.setText((base = stof.verbaas()) != null ? base.getNaam() : null); // Als base bestaat naam base, anders niks
		Stof zuur;
		txtAanpZuur.setText((zuur = stof.verzuur()) != null ? zuur.getNaam() : null); // Als zuur bestaat naam zuur, anders niks
		double kb;
		txtAanpKb.setText((kb = stof.getKb()) != -1 ? format.format(kb) : null); // Als stof een kb heeft, toon kb, anders niks
		double kz;
		txtAanpKz.setText((kz = stof.getKz()) != -1 ? format.format(kz) : null);
	}

	public void show(){
		frmDatabaseopties.setVisible(true);
	}

	public void hide(){
		frmDatabaseopties.setVisible(false);
	}


	private void tabChange(int index){
		switch (index){
		case TAB_TOEVOEGEN:
			frmDatabaseopties.setSize(450, frmDatabaseopties.getHeight());
			tabbedPane.setSize(434, tabbedPane.getHeight());
			break;
		case TAB_AANPASSEN:
			frmDatabaseopties.setSize(650, frmDatabaseopties.getHeight());
			tabbedPane.setSize(634, tabbedPane.getHeight());
			break;
		default:
			System.out.println("onbekende tab"); 	// Zou niet moeten gebeuren
			System.exit(1); 						// Daarom stoppen we ermee
			break;
		}
	}

	//TODO: maak base
	@SuppressWarnings("unused") // Mogelijk later gebruikt
	private String makeBase(String zuur){
		String base = "";
		int posCOOH = zuur.lastIndexOf("COOH");
		if (posCOOH == -1){
			//bij normaal zuur
			int posH = zuur.indexOf("H");//neemt de 1e H
			String s = "0123456789";
			if (s.indexOf(zuur.charAt(posH + 1)) > 0){			
				base = zuur.replace(String.valueOf(zuur.charAt(posH + 1)), String.valueOf(Integer.parseInt(String.valueOf(zuur.charAt(posH + 1) - 1))));
			}else{
				base = zuur.replace("H", "");
			}

		}else{
			//in het geval van een COOH-groep
			base = zuur.replace("COOH", "COO");
		}
		setLading(base);
		return base;
	}

	private String setLading(String incompleteBase){
		String base = incompleteBase;
		if (base.charAt(base.length()-1) == '-'){//laatste = -
			if (base.charAt(base.length()-2) == ' '){
				base.replace("-", "2-");
			}else{
				String c = String.valueOf(base.charAt(base.length()-2));
				int lading = Integer.parseInt(c);
				lading++;
				base.replace(String.valueOf(lading-1) + "-", String.valueOf(lading) + "-");
			}
		}else{
			if (base.charAt(base.length()-1) == '+'){
				if (base.charAt(base.length()-2) == ' '){
					base.replace(" +", "");
				}else{
					String c = String.valueOf(base.charAt(base.length()-2));
					int lading = Integer.parseInt(c);
					lading--;
					base.replace(String.valueOf(lading+1) + "+", String.valueOf(lading) + "+");
				}
			}else{
				base = base + "-";
			}
		}		
		return base;
	}

	private class StofHolder {

		private String naam;
		private Stof stof;

		private StofHolder(String naam, Stof stof){
			this.naam = naam;
			this.stof = stof;
		}

		@Override
		public String toString() {
			return naam;
		}
	}

	private void setStoffenArray(){
		Stof[] stoffenArray = Stof.getStoffen();
		for (int i = 0; i < stoffenArray.length; i++){
			Stof stof = stoffenArray[i];
			stoffen.addElement(new StofHolder(stof.getNaam(), stof));			
		}
	}
}
